if (counter != curCount) return;
display.scroller.scrollTop += outside;
off(document, "mousemove", move);
off(document, "mouseup", up);
doc.history.lastSelOrigin = null;
var move = operation(cm, function(e) { if (!e_button(e)) done(e);
var up = operation(cm, done);
on(document, "mousemove", move);
on(document, "mouseup", up);
function onTouchMove(e) { if (!e.touches || e.touches.length !== 1 || e.touches[0].radiusX>1 || e.touches[0].radiusY>1) return;
var cur = posFromMouse(cm, e);
if (!cmp(touchDrag, cur)) return;
extendSelection(cm.doc, clipPos(cm.doc, touchDrag), cur);
touchDrag = posFromMouse(cm, e);
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
off(document, "touchend", up);
var up = operation(cm, done);
on(document, "touchend", up);
function gutterEvent(cm, e, type, prevent, signalfn) { try { var mX = e.clientX, mY = e.clientY; } catch(e) { return false; } if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
if (prevent) e_preventDefault(e);
var display = cm.display;
var lineBox = display.lineDiv.getBoundingClientRect();
if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
mY -= lineBox.top - display.viewOffset;
for (var i = 0; i < cm.options.gutters.length; ++i) { var g = display.gutters.childNodes[i];
if (g && g.getBoundingClientRect().right >= mX) { var line = lineAtHeight(cm.doc, mY);
var gutter = cm.options.gutters[i];
signalfn(cm, type, cm, line, gutter, e);
return e_defaultPrevented(e);
function clickInGutter(cm, e) { return gutterEvent(cm, e, "gutterClick", true, signalLater);
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))